package com.chwl.framework.grpc;


import com.chwl.framework.grpc.discover.ServiceDiscoverService;
import com.chwl.framework.grpc.exception.ConnectionException;
import com.chwl.framework.grpc.exception.NotFoundException;
import com.chwl.framework.grpc.service.GrpcRequest;
import io.grpc.StatusRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 包名：com.anoyi.grpc<br>
 * <p>功能:</p>
 *
 * @date:2018-07-16 下午12:06<br/>
 * @version:1.0 <br/>
 */
public class GrpcClientService {
    private Logger logger = LoggerFactory.getLogger(GrpcClientService.class);
    private static GrpcClientService instance = new GrpcClientService();

    public static GrpcClientService getInstance() {
        return instance;
    }

    public Object invoke(String serviceName, String methodName, Object... args) throws Exception {
        return invoke(null, serviceName, methodName, args);
    }

    public Object invoke(String ip, String serviceName, String methodName, Object... args) throws Exception {
        GrpcRequest request = new GrpcRequest();
        request.setBeanName(serviceName);
        request.setMethodName(methodName);
        if (args != null && args.length != 0) {
            request.setArgs(args);
        }
        ServerContext context = null;
        try {
            context = ServiceDiscoverService.getInstance().findServer(serviceName, ip);
            return context.handle(request).getResult();
        } catch (NotFoundException e) {
            logger.error("invoke grpc service fail,serviceName:{},error message:{}", serviceName, e.getMessage(), e);
            throw e;
        } catch (ConnectionException | StatusRuntimeException e) {
            logger.error("invoke grpc service fail,serviceName:{},server:{},error message:{}", serviceName, context.getIp() + ":" + context.getPort(), e.getMessage(), e);
            return invoke(ip, serviceName, methodName, args);
        } catch (Exception e) {
            throw e;
        }
    }
}
